﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InHD.model;
using System.Data;
using InHD.utilities;

namespace InHD.dataaccess
{
    class CategoryRepository
    {
        #region Fields

        readonly List<Category> _categories;
        //For DB Utils
        private DBUltils _db;
        string[] _paramName;
        string[] _value;
        DBUltils.ParamType[] _paramType;
        #endregion // Fields

        #region Constructor

        public CategoryRepository()
        {
            _categories = new List<Category>();
            this._db = new DBUltils();
            if (!_db.connectDB(Constants.Security.DefaultDBUser, Constants.Security.DefaultDBPassword))
                throw new ArgumentNullException(Constants.Messages.CannotConnectDB);
        }

        #endregion // Constructor

        #region Public Interface

        public event EventHandler<CategoryAddedEventArgs> CategoryAdded;

        public string AddCategory(Category category)
        {
            try
            {
                if (category == null)
                    throw new ArgumentNullException("category");

                if (!_categories.Contains(category))
                {
                    //// Add new company info into database
                    if (_db == null)
                        throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                    if (category.CategoryUNK == null)
                        category.CategoryUNK = "Cat - " + Guid.NewGuid().ToString();
                    _paramName = new string[]{"@categoryUNK",
                                        "@name",
                                        "@description"};
                    _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr
                                                    };
                    _value = new string[]{category.CategoryUNK,
                                        category.Name,
                                        category.Description
                                    };

                    _db.queryDB(Constants.StoreProcedures.Category.AddCategory, _paramName, _paramType, _value, DBUltils.QueryType.Insert);
                    _categories.Add(category);

                    if (this.CategoryAdded != null)
                        this.CategoryAdded(this, new CategoryAddedEventArgs(category));
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
//            System.Windows.MessageBox.Show("Add category successfully!!!");
            return string.Empty;
        }

        public string EditCategory(Category category)
        {
            try
            {
                foreach (Category cat in this._categories)
                {
                    if (cat.CategoryUNK.Equals(category.CategoryUNK))
                    {
                        cat.Name = category.Name;
                        cat.Description = category.Description;
                        //update DB
                        if (_db == null)
                            throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                        if (category.CategoryUNK == null)
                            throw new ArgumentNullException("Null Unique key");
                        _paramName = new string[]{"@categoryUNK",
                                        "@name",
                                        "@description"};
                        _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr
                                                    };
                        _value = new string[]{category.CategoryUNK,
                                        category.Name,
                                        category.Description
                                    };

                        _db.queryDB(Constants.StoreProcedures.Category.UpdateCategory, _paramName, _paramType, _value, DBUltils.QueryType.Update);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
//            System.Windows.MessageBox.Show("Edit category successfully!!!");
            return string.Empty;
        }

        public string DeleteCategory(string categoryUNK)
        {
            bool found = false;
            foreach (Category category in this._categories)
            {
                if (category.CategoryUNK.Equals(categoryUNK))
                {
                    this._categories.Remove(category);
                    found = true;
                    break;
                }
            }
            if (!found)
                return "UNK is not exist";
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (categoryUNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[] { "@categoryUNK" };
                _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
                _value = new string[] { categoryUNK };

                _db.queryDB(Constants.StoreProcedures.Category.DeleteCategory, _paramName, _paramType, _value, DBUltils.QueryType.Delete);
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Delete Category successfully!!!");
            return string.Empty;
        }

        public List<Category> GetCategory()
        {
            return this._categories;
        }

        public string LoadAllCategories()
        {
            //// Get datatable of Category
            //DataTable dt = new DataTable();
            //dt.Columns.Add("Name");
            //dt.Columns.Add("Description");
            //dt.Columns.Add("CategoryUNK");
            //DataRow row = dt.NewRow();
            //row["CategoryUNK"] = "Cat - " + Guid.NewGuid().ToString();
            //row["Name"] = "Category 1";
            //row["Description"] = "Category 1";
            //dt.Rows.Add(row);
            //row = dt.NewRow();
            //row["CategoryUNK"] = "Cat - " + Guid.NewGuid().ToString();
            //row["Name"] = "Category 2";
            //row["Description"] = "Category 2";
            //dt.Rows.Add(row);
            //dt.AcceptChanges();
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                _paramName = new string[] { };
                _paramType = new DBUltils.ParamType[] { };
                _value = new string[] { };
                DataSet ds = _db.queryDB(Constants.StoreProcedures.Category.GetAllCategories, _paramName, _paramType, _value, DBUltils.QueryType.Select);

                foreach (DataRow r in ds.Tables[0].Rows)
                {
                    this._categories.Add(Category.CreateCategoryInfo(Convert.ToString(r["catDescrp"]), Convert.ToString(r["name"]), Convert.ToString(r["categoryUNK"])));
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            return string.Empty;
        }

        public bool CategoryExist { get { return (this._categories.Count > 0); } }

        public Category CategoryInformation { get { return this.CategoryExist ? this._categories[0] : null; } }

        #endregion // Public Interface

        #region Private Helpers

        #endregion // Private Helpers

        internal string DeleteCategory(Category category)
        {
            return string.Empty;
        }
    }
}
